using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using System.ComponentModel;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio;
using System.IO;

namespace Ferpect.GameComponents.Design
{
    public class DesignTimeContentManager : ContentManager
    {
        private EnvDTE.Project project;

        public DesignTimeContentManager(IServiceProvider serviceProvider, EnvDTE.Project project)
            : base(serviceProvider)
        {
            if (project == null) throw new ArgumentNullException("project");
            this.project = project;
        }

        protected override System.IO.Stream OpenStream(string assetName)
        {
            string designTimeAssetName = this.GetDesignTimeAssetName(assetName);
            if (designTimeAssetName == assetName)
            {
                // The asset wasn't found.
                throw new ContentLoadException(String.Format("Could not find asset '{0}'. Please ensure that the item has built successfully before loading it into the designer.", assetName));
            }
            return base.OpenStream(designTimeAssetName);
        }

        private string GetDesignTimeAssetName(string assetName)
        {
            IVsHierarchy hierarchy = DesignerUtilities.GetHierarchyForProject(this.project);
            IList<IVsHierarchy> contentHierarchies = DesignerUtilities.GetNestedContentProjects(hierarchy);

            string projectDirectory = this.project.Properties.Item("FullPath").Value as string;
            string outputPathProperty = this.project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value as string;
            string outputDirectory = Path.Combine(projectDirectory, outputPathProperty);

            List<string> possibleNames = new List<string>(contentHierarchies.Count);
            foreach (IVsHierarchy contentHierarchy in contentHierarchies)
            {
                IVsBuildPropertyStorage buildProperties = (IVsBuildPropertyStorage)contentHierarchy;
                string contentRootDirectory;
                if (ErrorHandler.Succeeded(buildProperties.GetPropertyValue("ContentRootDirectory", String.Empty, (uint)_PersistStorageType.PST_PROJECT_FILE, out contentRootDirectory)))
                {
                    string possibleName = Path.Combine(contentRootDirectory, assetName);
                    possibleName = Path.Combine(outputDirectory, possibleName);
                    if (File.Exists(possibleName + ".xnb"))
                    {
                        possibleNames.Add(possibleName);
                    }
                }
            }
            if (possibleNames.Count == 1)
            {
                return possibleNames[0];
            }
            return assetName;
        }
    }
}
